package nccloud.sso.servlet;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import nc.bs.framework.adaptor.IHttpServletAdaptor;
import nc.bs.framework.common.RuntimeEnv;
import nc.bs.logging.Logger;
import nc.vo.pub.BusinessException;
import nccloud.sso.dto.SSOParamDTO;
import nccloud.sso.util.SSOUtils;

@SuppressWarnings({ "serial", "restriction"})
public class SSOVisitServlet extends HttpServlet implements IHttpServletAdaptor {

	@Override
	public void doAction(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		SSOParamDTO param = null; 
		try {
			// 1.参数解析
			param = this.parseParam(req);
			// 2.校验
			param = this.checkParam(param);
			// 3.参数填充
			param = this.fillParam(param);
			// 4.token获取 
			String token = this.getToken(param);
			// 5.重定向地址生成
			String redirectUrl = this.generateRedirectUrl(token, param);

//			String redirectUrl = "/nccloud/resources/workbench/public/common/main/index.html#/";
			//解决跨域问题
			resp.setHeader("Access-Control-Allow-Origin", "*");
			resp.setHeader("referrer","no-referrer");
			
			// 6.重定向
			resp.sendRedirect(redirectUrl);
		} catch (IllegalArgumentException e) {
			this.handleException(resp, e, param, e.getMessage());
		} catch (Exception e) {
			this.handleException(resp, e, param, "单点登录出现错误");
		}
	}

	/**
	 * 解析参数 生成DTO
	 * 
	 * @param req
	 * @return
	 */
	@SuppressWarnings("restriction")
	private SSOParamDTO parseParam(HttpServletRequest req) {
		SSOParamDTO dto = new SSOParamDTO();
		String c = (String) req.getAttribute("c");
		String p = (String) req.getAttribute("p");
		String pk_bill = (String) req.getAttribute("pk_bill");
		String pk_message = (String)req.getAttribute("pk_message");
		dto.setPk_bill(pk_bill);
		if(c!=null && pk_bill!=null && pk_message!=null) {
			dto.setOpenType("1");//1 审批详情页面
		}else if(c!=null && pk_bill!=null && pk_message==null) {
			dto.setOpenType("2");//2单据详情页面
			dto.setAppcode((String) req.getAttribute("c"));
			dto.setPagecode((String) req.getAttribute("p"));
		}else if(c!=null && pk_bill==null && pk_message==null){
			dto.setOpenType("3");//3单据新增页面
			dto.setAppcode((String) req.getAttribute("c"));
			dto.setPagecode((String) req.getAttribute("p"));
		}else {
			dto.setOpenType("4");//4首页 
		}
		dto.setUsercode((String) req.getAttribute("usercode"));
		dto.setC((String) req.getAttribute("c"));
		dto.setP((String) req.getAttribute("p"));
		
		dto.setTradetype((String) req.getAttribute("tradetype"));
		
		dto.setPk_message((String)req.getAttribute("pk_message")); 
		Object srcType = req.getAttribute("srcType");
		dto.setSrcType(srcType == null ? 3 : (int)srcType);
		return dto;
	}

	/**
	 * 校验参数(主要校验传递过来的参数)
	 * 
	 * @param param
	 * @return
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	private SSOParamDTO checkParam(SSOParamDTO param) throws Exception {
		if (param.getUsercode() == null) {
			throw new IllegalArgumentException("无法识别用户，拒绝访问");
		}
		if ("1".equals(param.getOpenType()) && (param.getPk_message() == null || param.getPk_bill() == null || param.getC() == null || param.getP() == null)) {
			throw new IllegalArgumentException("传递参数缺失，无法跳转审批详情页面！");
		}
		if ("2".equals(param.getOpenType()) && (param.getPk_bill() == null || param.getC() == null || param.getP() == null)) {
			throw new IllegalArgumentException("传递参数缺失，无法跳转单据详情页面！");
		}
		if ("3".equals(param.getOpenType()) && (param.getC() == null || param.getP() == null)) {
			throw new IllegalArgumentException("传递参数缺失，无法跳转单据新增页面！");
		}
		
		return param;
	}

	/**
	 * 参数填充
	 * 
	 * @return
	 * @throws BusinessException
	 */
	private SSOParamDTO fillParam(SSOParamDTO param) throws Exception {
		if ("1".equals(param.getOpenType())) {
			// 注册数据查询需要的token
//			NCLocator.getInstance().lookup(ISecurityTokenCallback.class).token("NCSystem".getBytes(),"pfxx".getBytes());
//			IUAPQueryBS querysv = NCLocator.getInstance().lookup(IUAPQueryBS.class);
//			// 填充PK_MESSAGE MSGSOURCETYPE
//			String[] data = (String[]) querysv
//					.executeQuery("select "+ 
//							"       sm_msg_approve.MSGSOURCETYPE,\r\n" + 
//							"       sm_msg_approve.PK_MESSAGE\r\n" + 
//							"  from sm_msg_user\r\n" + 
//							"  left join sm_msg_approve\r\n" + 
//							"    on sm_msg_user.pk_message = sm_msg_approve.pk_message\r\n" + 
//							" where sm_msg_approve.billid = '"+ param.getPk_bill()+"'\r\n" + 
//							"   and sm_msg_user.destination = 'inbox'\r\n" + 
//							"   and sm_msg_user.isdelete = 'N'\r\n" + 
//							"   and sm_msg_user.pk_message = '"+ param.getPk_message()+"'\r\n" +
//							" order by sm_msg_user.ts desc"
//							 , new ResultSetProcessor() {
//								@Override
//								public Object handleResultSet(ResultSet rs) throws SQLException {
//									if (rs.next()) {
//										return new String[] { rs.getString("PK_MESSAGE"),
//												rs.getString("MSGSOURCETYPE") };
//									}
//									return null;
//								}
//							});
//			if (data == null)
//				throw new IllegalArgumentException("无此审批信息");
//			param.setPk_message(data[0]);
//			param.setPageMsgType(data[1]);
		}
		SSOUtils.loadSysParam(param);
		return param;
	}

	/**
	 * 获取token
	 * 
	 * @param param
	 * @return
	 * @throws Exception
	 */
	private String getToken(SSOParamDTO param) throws Exception {
		String token = null;
		while(token==null||"".equals(token)) {
			token = SSOUtils.reqToken(param);
		}
		return token;
	}

	/**
	 * 生成重定向地址
	 * 
	 * @param param
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private String generateRedirectUrl(String token, SSOParamDTO param) throws Exception {
		boolean isDevelopMode = RuntimeEnv.getInstance().isDevelopMode();
		StringBuilder url = new StringBuilder();
		String preUri = SSOUtils.URL_PREFIX + param.getIp() + SSOUtils.COLON + param.getPort();
		url.append(preUri);
		url.append(isDevelopMode ? "/uap/rbac/thirdpartylogin/main/index.html?" : "/nccloud/resources/uap/rbac/thirdpartylogin/main/index.html?");
		url.append("accesstoken=").append(token).append("&redirect_uri=").append(preUri).append("/nccloud/resources/workbench/public/common/main/index.html#/");
		
		if("1".equals(param.getOpenType())) {
			url.append( "ifr?ifr=" + param.toApproveUrlParam());
		}else if("2".equals(param.getOpenType())) {
			url.append( "ifr?ifr=" + param.toBillBrowseUrlParam());
		}else if("3".equals(param.getOpenType())) {
			url.append( "ifr?ifr=" + param.toBillAddUrlParam());
		}
		
		return url.toString();
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		this.doGet(req, resp);
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html; charset=UTF-8");
		this.doAction(req, resp);
	}

	/**
	 * 异常处理
	 * 
	 * @param e
	 * @param param
	 * @param showMsg
	 * @throws IOException
	 */
	private void handleException(HttpServletResponse resp, Exception e, SSOParamDTO param, String showMsg)
			throws IOException {
		this.recordError(e, param);
		resp.getWriter().write(showMsg + " ---- 3秒后跳到NCC登录页面");
		resp.setHeader("refresh", "3;url=/nccloud/resources/uap/rbac/login/main/index.html");
	}

	/**
	 * 错误日志记录
	 * 
	 * @param e
	 * @param param
	 */
	private void recordError(Exception e, SSOParamDTO param) {
		Logger.error("SSO::SSOVisitServlet.doAction");
		Logger.error(e.getMessage());
		Logger.error("SSO::调用栈");
		StringWriter sw = new StringWriter();
		e.printStackTrace(new PrintWriter(sw, true));
		Logger.error(sw.getBuffer().toString());
		if(null!=param) {
			Logger.error("SSO::DTO参数");
			Logger.error(param.toString());
		}else {
			Logger.error("SSO::DTO参数为空");
		}
	}
}
